/**
 * 我将 路径漫游（轨迹跟随） 与 绕点旋转（环绕观察） 两种视角漫游模式集成在一起
 * 路径漫游（Path Roaming）：跟随 JSON 路径前进，支持插值、暂停、速度调节等。
 * 绕点旋转（Orbit Roaming）：相机以固定半径绕指定点自动旋转，支持调整速度和角度。
 * 可以通过参数在两种模式之间切换。 useCameraRoaming.ts
 */
import { SuperMap3D } from '@/utils/supermap3d';
export interface CameraPathNode {
  position: { x: number; y: number; z: number };
  heading: number;
  pitch: number;
  roll: number;
}

type RoamingMode = 'path' | 'orbit';

export function useCameraRoaming(viewer: any | undefined) {
  let path: CameraPathNode[] = [];
  let timer: number | null = null;
  let isPaused = false;
  let currentStep = 0;
  let speed = 0.002;
  let mode: RoamingMode = 'path';

  // 绕点旋转相关
  let angle = 0;
  let orbitCenter = { x: 0, y: 0, z: 0 };
  let orbitRadius = 10;
  let orbitSpeed = 0.01;

  function interpolateNodes(n1: CameraPathNode, n2: CameraPathNode, t: number): CameraPathNode {
    const interp = (a: number, b: number) => a + (b - a) * t;
    return {
      position: {
        x: interp(n1.position.x, n2.position.x),
        y: interp(n1.position.y, n2.position.y),
        z: interp(n1.position.z, n2.position.z),
      },
      heading: interp(n1.heading, n2.heading),
      pitch: interp(n1.pitch, n2.pitch),
      roll: interp(n1.roll, n2.roll),
    };
  }

  function roamFrame() {
    if (!viewer || isPaused) return;

    if (mode === 'path') {
      const idx = Math.floor(currentStep);
      if (idx >= path.length - 1) {
        stop();
        return;
      }

      const t = currentStep - idx;
      const node = interpolateNodes(path[idx], path[idx + 1], t);

      const pos = SuperMap3D.Cartesian3.fromDegrees(node.position.x, node.position.y, node.position.z);
      viewer.scene.camera.setView({
        destination: pos,
        orientation: {
          heading: SuperMap3D.Math.toRadians(node.heading),
          pitch: SuperMap3D.Math.toRadians(node.pitch),
          roll: SuperMap3D.Math.toRadians(node.roll),
        },
      });

      currentStep += speed;
    } else if (mode === 'orbit') {
      angle += orbitSpeed;
      if (angle > Math.PI * 2) angle -= Math.PI * 2;

      const x = orbitCenter.x + orbitRadius * Math.cos(angle);
      const y = orbitCenter.y + orbitRadius * Math.sin(angle);
      const z = orbitCenter.z;

      const position = SuperMap3D.Cartesian3.fromDegrees(x, y, z);
      const center = SuperMap3D.Cartesian3.fromDegrees(orbitCenter.x, orbitCenter.y, orbitCenter.z);
      viewer.scene.camera.setView({
        destination: position,
        orientation: {
          heading: viewer.scene.camera.heading,
          pitch: viewer.scene.camera.pitch,
          roll: 0,
        },
      });
      viewer.scene.camera.lookAt(center, new SuperMap3D.HeadingPitchRange(0, 0, orbitRadius));
    }

    timer = requestAnimationFrame(roamFrame);
  }

  function startPathRoaming(p: CameraPathNode[], spd = 0.002) {
    stop();
    mode = 'path';
    path = p;
    currentStep = 0;
    speed = spd;
    isPaused = false;
    roamFrame();
  }

  function startOrbitRoaming(center: { x: number; y: number; z: number }, radius = 10, spd = 0.01) {
    stop();
    mode = 'orbit';
    orbitCenter = center;
    orbitRadius = radius;
    orbitSpeed = spd;
    angle = 0;
    isPaused = false;
    roamFrame();
  }

  function pause() {
    isPaused = true;
    if (timer) cancelAnimationFrame(timer);
  }

  function resume() {
    if (!isPaused) return;
    isPaused = false;
    roamFrame();
  }

  function stop() {
    if (timer) cancelAnimationFrame(timer);
    timer = null;
    isPaused = false;
    currentStep = 0;
  }

  return {
    //启动路径漫游
    startPathRoaming,
    //启动绕点旋转
    startOrbitRoaming,
    //暂停
    pause,
    //恢复
    resume,
    //停止
    stop,
    //设置速度
    setSpeed: (spd: number) => (speed = spd),
    //设置路径
    setPath: (p: CameraPathNode[]) => (path = p),
    //设置中心点
    setOrbitSpeed: (spd: number) => (orbitSpeed = spd),
    //设置半径
    setOrbitRadius: (r: number) => (orbitRadius = r),
  };
}
